<?php
declare (strict_types = 1);

namespace app\admin\controller\projects;

use app\admin\controller\AuthController;
use app\admin\model\project\ProjectColumns;
use app\admin\model\project\Projects;
use app\admin\model\project\ProjectTaskJobs;
use app\admin\model\project\ProjectTaskLogs;
use app\admin\model\project\ProjectTasks;
use app\admin\model\project\ProWorkdays;
use app\admin\model\project\Swimlanes;
use app\admin\model\system\SystemMenus;
use bbweb\services\UtilService as Util;
use bbweb\utils\Avatar;
use think\Exception;
use think\facade\Config;
use think\facade\Db;
use think\Request;

class Produce extends AuthController
{
    /**
     * @param Request $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function index(Request $req)
    {
        //echo ProWorkdays::getWorkingHours(1615537745, 1615688418);
        //echo ProWorkdays::getWorkingHours(1615725465, 1615778011);
        $statuss = Config::get('hello.pro_status', [0=>'待启动', 1=>'施工中', 2=>'已完成']);
        $types = Db::name('project_types')->column('name', 'id');
        $uid = (int) $this->adminId;
        if ($req->isAjax()) {
            $data = [];
            $page = $req->param('page/d', 1);
            $limit = $req->param('limit/d', 15);
            $query = Db::name('projects')->alias('a')
                ->leftJoin('system_admin m', 'm.id = a.owner_id')
                ->leftJoin('system_admin u', 'u.id = a.uid')
                ->where(function ($query) use($uid) {
                    $query->where('FIND_IN_SET(:uid,`a`.`owner_id`)',['uid' => $uid])
                        ->whereOr('FIND_IN_SET(:uid,`a`.`audit_id`)',['uid' => $uid])
                        ->whereOr('FIND_IN_SET(:uid,`a`.`teams`)',['uid' => $uid]);
                })
                ->where('a.start_at', '>', 0)
                ->where('a.status', '>', 0)
                ->where('a.is_delete', 0)
                ->field('a.*, m.real_name as owner_name, u.real_name as account');
            // 条件搜索
            $status = $req->param('status');
            if (!is_null($status) && strlen($status)) {
                $query->where('a.status','=',$status);
            }
            $type = $req->param('type');
            if (!is_null($type) && strlen($type)) {
                $query->where('a.type','=',$type);
            }
            $sys = $req->param('sys');
            if (!is_null($sys) && strlen($sys)) {
                $query->where('a.sys','=',$sys);
            }
            $name = $req->param('name');
            if (!is_null($name) && strlen($name)) {
                $query->where('a.name','like',"%$name%");
            }

            $query->order('a.id DESC');
            $data['count'] = $query->count('a.id');
            $data['data'] = $query->page($page,$limit)->select()->toArray();
            //echo $query->getLastSql();die;
            $data['code'] = 0;
            $data['msg'] = '';
            foreach ($data['data'] as &$val) {
                $val['statustext'] = $statuss[$val['status']] ?? '--/--';
                $val['typetext'] = $types[$val['type']] ?? '--/--';
                $val['progress_list'] = $val['progress_list'] ? array_merge(json_decode($val['progress_list'], true)) : [];
                $progress = get_progress($val['start_at'], $val['end_at'], $val['finish_at']);
                $val['progress'] = $progress['progress'];
                $val['progress_color'] = $progress['color'];
                $val['create_at'] = $val['create_at'] ? date('Y-m-d',$val['create_at']) : '--/--';
                $val['finish_at'] = $val['finish_at'] ? date('Y-m-d',$val['finish_at']) : '--/--';
                $val['start_at'] = $val['start_at'] ? date('Y-m-d',$val['start_at']) : '--/--';
                $val['end_at'] = $val['end_at'] ? date('Y-m-d',$val['end_at']) : '--/--';
                $val['account'] = $val['account'] ?? '--/--';
                $val['owner_name'] = $val['owner_name'] ?? '--/--';
            }

            return json($data);
        }
        $sonAuth = SystemMenus::getSonAuth($req->controller(), $req->action(),array_keys($this->auth));

        // 显示页面
        $this->assign('statuss', $statuss);
        $this->assign('sonAuth', $sonAuth);
        $this->assign('types', $types);
        return $this->fetch();
    }

    /**
     * 分配器
     * @param Request $req
     * @return string
     * @throws \Exception
     */
    public function show(Request $req)
    {
        $op = $req->param('op', 'board');
        switch ($op) {
            case 'board':
                return $this->showBoard($req);
            case 'check':
                return $this->showCheck($req);
            case 'add'://添加任务
                return $this->taskAdd($req);
            case 'edit'://修改任务
                return $this->taskEdit($req);
            case 'log'://任务日志
                return $this->taskLog($req);
            case 'del'://删除任务
                return $this->taskDel($req);
            case 'audit'://评测
                return $this->taskAudit($req);
            case 'show'://查看任务
                return $this->showTask($req);
            case 'success'://查看任务
                return $this->taskSuccess($req);
            case 'change'://收缩展示
                return $this->change($req);
            case 'swimlane'://泳道列表
                return $this->swimlane($req);
            case 'swimlaneAdd'://添加泳道
                return $this->swimlaneAdd($req);
            case 'swimlaneEdit'://修改泳道
                return $this->swimlaneEdit($req);
            case 'swimlaneDel'://删除泳道
                return $this->swimlaneDel($req);
            default://概览
                return $this->showBasic($req);
        }
    }

    /**
     * @param Request $req
     */
    private function showCheck(Request $req)
    {
        $id = intval($req->param('id/d'));
        $timestamp = intval($req->param('timestamp/d'));
        if(!$id || !$timestamp) $this->error('参数错误');
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误');
        if($pro['update_at'] > $timestamp) {
            return json(['code'=>1,'msg'=>'ok']);
        }
        return json(['code'=>0,'msg'=>'ok']);
    }
    /**
     * 任务概览
     * @param Request $req
     * @return string
     * @throws \Exception
     */
    private function showBasic(Request $req)
    {
        $id = intval($req->param('id/d'));
        if(!$id) $this->error('参数错误');
        $uid = (int) $this->adminId;
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误');
        if($pro['is_delete']) $this->exception('项目已删除');
        $pro_owners = explode(',', $pro['owner_id']);
        $pro_teams = explode(',', $pro['teams']);
        $pro_audits = explode(',', $pro['audit_id']);
        if(!in_array($uid, $pro_owners) && !in_array($uid, $pro_audits) && !in_array($uid, $pro_teams)) $this->exception('无权访问该项目');
        if(!$pro['start_at']) $this->exception('项目未启动');
        $pro['images'] = !empty($pro['images']) ? explode('|',$pro['images']) : [];
        $statuss = Config::get('hello.pro_status', [0=>'待启动', 1=>'施工中', 2=>'已完成']);
        $pro['statustext'] = $statuss[$pro['status']] ?? '--/--';
        $this->assign('pro', $pro);
        $this->assign('uid', $uid);
        $account = $pro['uid'] ? Db::name('system_admin')->where('id',$pro['uid'])->value('real_name') : '--/--';
        $owners = $pro['owner_id'] ? Db::name('system_admin')->where('id', 'IN',$pro['owner_id'])->column('real_name', 'id') : ['--/--'];
        $audits = $pro['audit_id'] ? Db::name('system_admin')->where('id', 'IN',$pro['audit_id'])->column('real_name', 'id') : ['--/--'];
        $teams = $pro['teams'] ? Db::name('system_admin')->where('id', 'IN', $pro['teams'])->column('real_name', 'id') : ['--/--'];

        $events = ProjectTaskLogs::where('project_id', $id)->order('id DESC')->limit(20)->select();
        if($pro['status']==1) {
            $success_status = ProjectTasks::where('project_id',$pro['id'])->where('status','<',2)->where('is_delete',0)->count('id') == 0 && ProjectTasks::where('project_id',$pro['id'])->where('status','=',2)->where('is_delete',0)->count('id') > 0;
        } else {
            $success_status = false;
        }
        $this->assign('account', $account);
        $this->assign('pro_owners', $pro_owners);
        $this->assign('owners', $owners);
        $this->assign('teams', $teams);
        $this->assign('audits', $audits);
        $this->assign('events', $events);
        $this->assign('success_status', $success_status);
        return $this->fetch('info');
    }

    /**
     * 操纵台
     * @param $req
     * @return string
     * @throws \Exception
     */
    private function showBoard($req)
    {
        $id = intval($req->param('id/d'));
        if(!$id) $this->error('参数错误');
        $uid = (int) $this->adminId;
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误');
        if($pro['is_delete']) $this->exception('项目已删除');
        $pro_owners = explode(',', $pro['owner_id']);
        $pro_teams = explode(',', $pro['teams']);
        $pro_audits = explode(',', $pro['audit_id']);
        if(!in_array($uid, $pro_owners) && !in_array($uid, $pro_audits) && !in_array($uid, $pro_teams)) $this->exception('无权访问该项目');
        if(!$pro['start_at']) $this->exception('项目未启动');

        if ($req->isAjax()) {
            $data = Util::postMore([
                ['task_id', 0],//任务ID
                ['src_column_id', 0],//原栏目
                ['dst_column_id', 0],//移至栏目
                ['swimlane_id', 0],//新的泳道
                ['position', 1],//新的位置
            ]);
            $check = ProjectTasks::checkMove($uid, $data);
            if(!$check['code']) {
                $this->error($check['msg']);
            }
            ProjectTasks::beginTrans();
            try {
                $move = ProjectTasks::movePosition($id, $data['task_id'], $data['dst_column_id'], $data['position'], $data['swimlane_id'], true, $pro['audit_id']);
                if( !$move ) {
                    throw new \think\Exception('移动失败请重试！');
                }
                Projects::where('id',$id)->update(['update_at'=>time()]);
                ProjectTasks::commitTrans();
            } catch(\Exception $e) {
                ProjectTasks::rollbackTrans();
                return json(['code'=>0, 'msg'=>$e->getMessage()]);
            }
            $this->success('ok');
        }

        $pro['images'] = !empty($pro['images']) ? explode('|',$pro['images']) : [];
        $statuss = Config::get('hello.pro_status', [0=>'待启动', 1=>'施工中', 2=>'已完成']);
        $deeps = Config::get('hello.pro_deeps', [1=>'低', 2=>'中', 3=>'高', 4=>'紧急']);
        $pro['statustext'] = $statuss[$pro['status']] ?? '--/--';
        $collapsed = Db::name('project_user_event')->where('project_id', $pro['id'])->where('uid', $uid)->where('event','collapsed')->find() ? 1 : 0;
        $owner_id_only = Db::name('project_user_event')->where('project_id', $pro['id'])->where('uid', $uid)->where('event','only')->find() ? $uid : 0;
        $this->assign('pro', $pro);
        $this->assign('uid', $uid);
        $this->assign('pro_owners', $pro_owners);
        $this->assign('collapsed', $collapsed);
        $this->assign('owner_id_only', $owner_id_only);
        $sonAuth = SystemMenus::getSonAuth($req->controller(), 'index',array_keys($this->auth));
        $this->assign('sonAuth', $sonAuth);

        $users = [];
        $swimlanes = Swimlanes::getSwimlanes($pro['id']);
        $columns = ProjectColumns::getColumn($pro['id']);
        $avatar = new Avatar();
        $tasks = [];
        foreach ($swimlanes as $sv) {
            $tasks['swimlanes'][$sv['id']]['swim'] = $sv;
            $tasks['swimlanes'][$sv['id']]['column'] = 0;//泳道任务数
            foreach ($columns as $cv) {
                $tasks['column'.$cv['position']] = $pro['progress_list'][$cv['position']]['total'] ?? 0;
                $tasks['swimlanes'][$sv['id']]['columns'][$cv['position']] = $cv;
                $tasks['swimlanes'][$sv['id']]['columns'][$cv['position']]['column'] = 0;//栏目任务数
                $tasks['swimlanes'][$sv['id']]['columns'][$cv['position']]['lists'] = [];
            }
        }
        $data = ProjectTasks::getTasks($pro['id'], $owner_id_only);
        foreach ($data as $key=>$val) {
            if(!isset($users[$val['owner_id']])) {
                $user = Db::name('system_admin')->where('id', $val['owner_id'])->field('id,real_name')->find();
                if($user) {
                    $user['owner_avatar'] = $avatar->render($user['real_name']);
                    $users[$val['owner_id']] = $user;
                } else {
                    $users[$val['owner_id']] = ['id'=>0,'real_name'=>'--/--','owner_avatar'=>'rgb(176 176 176)'];
                }
            }
            $val['owner_name'] = $users[$val['owner_id']]['real_name'];
            $val['owner_avatar'] = $users[$val['owner_id']]['owner_avatar'];
            $val['estimated'] = $val['time_spent'] .'/'. $val['time_estimated'] .'h';
            $val['task_links'] = 0;
            $val['end_date'] = $val['end_at'] ? date('Y/m/d', $val['end_at']) : '';
            $val['deep_name'] = $deeps[$val['deep']];
            $tasks['swimlanes'][$val['swimlane_id']]['columns'][$val['column_id']]['lists'][] = $val;
            $tasks['swimlanes'][$val['swimlane_id']]['column'] += 1;
            $tasks['swimlanes'][$val['swimlane_id']]['columns'][$val['column_id']]['column'] += 1;
        }
        if($pro['status']==1) {
            $success_status = ProjectTasks::where('project_id',$pro['id'])->where('status','<',2)->where('is_delete',0)->count('id') == 0 && ProjectTasks::where('project_id',$pro['id'])->where('status','=',2)->where('is_delete',0)->count('id') > 0;
        } else {
            $success_status = false;
        }
        $this->assign('tasks', $tasks);
        $this->assign('success_status', $success_status);
        return $this->fetch();
    }

    private function taskSuccess($req)
    {
        $id = intval($req->param('id/d'));
        if(!$id) $this->error('参数错误');
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误');
        if($pro['is_delete']) $this->error('项目已删除');
        $pro_owners = explode(',', $pro['owner_id']);
        if(!in_array($uid, $pro_owners)) $this->error('该项目您无权操作');
        $success_status = ProjectTasks::where('project_id',$pro['id'])->where('status','<',2)->where('is_delete',0)->count('id') == 0 && ProjectTasks::where('project_id',$pro['id'])->where('status','=',2)->where('is_delete',0)->count('id') > 0;

        if(!$success_status) {
            $this->error('该项目还有小任务未完成');
        }
        if($req->isAjax()) {
            $res = Projects::update([
                'status'    => 2,
                'finish_at' => time(),
                'update_at' => time(),
            ], ['id'=>$id]);
            if($res) {
                return json(['code'=>2, 'msg'=>'恭喜、项目已完成，同志们辛苦了']);
            } else {
                $this->error();
            }
        }
    }

    /**
     * 查看任务
     * @param Request $req
     * @return string
     * @throws \Exception
     */
    private function showTask(Request $req)
    {
        $id = intval($req->param('id/d'));
        $task_id = intval($req->param('task_id/d'));
        if(!$id || !$task_id) $this->error('参数错误');
        $uid = (int) $this->adminId;
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误');
        if($pro['is_delete']) $this->exception('项目已删除');
        $task = ProjectTasks::find(['id'=>$task_id]);
        if(!$task || $task['is_delete']) $this->error('项目不存在或已删除','',-1);
        $statuss = Config::get('hello.pro_status', [0=>'待启动', 1=>'施工中', 2=>'已完成']);
        $pro['statustext'] = $statuss[$pro['status']] ?? '--/--';
        $this->assign('pro', $pro);
        $this->assign('uid', $uid);
        //创建者
        $account = $pro['uid'] ? Db::name('system_admin')->where('id',$task['uid'])->value('real_name') : '--/--';
        //接受者
        $owner_name = $pro['owner_id'] ? Db::name('system_admin')->where('id',$task['owner_id'])->value('real_name') : '--/--';
        $audit = $pro['audit_id'] ? Db::name('system_admin')->where('id',$pro['audit_id'])->value('real_name') : '--/--';
        $events = ProjectTaskLogs::where('task_id', $task_id)->where('project_id', $id)->order('id DESC')->select();
        $jobs = ProjectTaskJobs::where('task_id', $task_id)->where('project_id', $id)->order('id DESC')->select();
        $columns = ProjectColumns::getColumn($pro['id']);
        $task['column_name'] = $columns[$task['column_id']] ? $columns[$task['column_id']]['title'] : '--/--';

        $time_work = '--/--';
        if($task['status'] > 0 ) {
            if( $task['time_estimated'] > $task['time_spent'] ) {
                $time_work = '提前'. round($task['time_estimated'] - $task['time_spent'], 1). 'h';
            } else if( round($task['time_estimated']) == round($task['time_spent']) ) {
                $time_work = '按时完成';
            } else {
                $time_work = '超时'. round($task['time_spent'] - $task['time_estimated'], 1) .'h';
            }
        }
        $task['time_work'] = $time_work;

        $deeps = Config::get('hello.pro_deeps', [1=>'低', 2=>'中', 3=>'高', 4=>'紧急']);
        $task['deep_name'] = $deeps[$task['deep']];
        $task['create_date'] = $task['create_at'] ? date('Y-m-d H:i',$task['create_at']) : '--/--';
        $task['start_date'] = $task['start_at'] ? date('Y-m-d H:i',$task['start_at']) : '--/--';
        $task['end_date'] = $task['end_at'] ? date('Y-m-d H:i',$task['end_at']) : '--/--';

        $this->assign('account', $account);
        $this->assign('owner_name', $owner_name);
        $this->assign('audit', $audit);
        $this->assign('events', $events);
        $this->assign('jobs', $jobs);
        $this->assign('task', $task);
        return $this->fetch('task_info');
    }

    /**
     * 添加日志
     * @param $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function taskLog($req)
    {
        $id = intval($req->param('id/d'));
        $task_id = intval($req->param('task_id/d'));
        if(!$id || !$task_id) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $task = ProjectTasks::find(['id'=>$task_id]);
        if(!$task || $task['is_delete']) $this->error('项目不存在或已删除','',-1);

        if ($req->isPost()) {
            $data = Util::postMore([
                ['job', '']
            ]);
            if (!$data['job']) $this->error('请输入日志内容');
            $data['project_id'] = $pro['id'];
            $data['task_id'] = $task_id;
            $data['create_at'] = time();
            $res = ProjectTaskJobs::addJobs($data);
            if($res) {
                $this->success('操作成功','', [], 2);
            } else {
                $this->error();
            }
        }
        return $this->fetch('add_log');
    }

    /**
     * 评测
     * @param $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function taskAudit($req)
    {
        $id = intval($req->param('id/d'));
        $task_id = intval($req->param('task_id/d'));
        if(!$id || !$task_id) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $pro_audits = explode(',', $pro['audit_id']);
        if(!in_array($uid, $pro_audits)) $this->error('该项目您无评测权限','',-1);
        $task = ProjectTasks::find(['id'=>$task_id]);
        if(!$task || $task['is_delete']) $this->error('项目不存在或已删除','',-1);

        if ($req->isPost()) {
            $data = Util::postMore([
                ['rate', 5],
                ['rate_punish', 0],
                ['punish_desc', ''],
            ]);
            if ($data['rate_punish']!=0 && empty($data['punish_desc'])) $this->error('请输入处罚缘由');
            $data['status'] = 2;
            $data['rate_at'] = time();//评分生效
            $data['update_at'] = time();
            ProjectTasks::beginTrans();
            try {
                $res = ProjectTasks::update($data, ['id'=>$task_id]);
                if(!$res) {
                    throw new \think\Exception('评测写入失败！');
                }
                $res = ProjectTasks::toolTaskRate($task_id);
                if(!$res) {
                    throw new \think\Exception('任务评分失败！');
                }
                Projects::update(['update_at'=>time()], ['id'=>$id]);
                ProjectTasks::commitTrans();
            } catch (Exception $e) {
                ProjectTasks::rollbackTrans();
                return json(['code'=>0, 'msg'=>$e->getMessage()]);
            }
            return json(['code'=>2, 'msg'=>'测评成功']);
        }
        $this->assign('task', $task);
        return $this->fetch('task_audit');
    }
    /**
     * 添加任务
     * @param $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function taskAdd($req)
    {
        $id = intval($req->param('id/d'));
        if(!$id) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $pro_owners = explode(',', $pro['owner_id']);
        if(!in_array($uid, $pro_owners)) $this->error('该项目您无权添加任务','',-1);
        $swimlane_id = intval($req->param('swimlane_id/d'));

        if ($req->isPost()) {
            $data = Util::postMore([
                ['title', ''],
                ['description', ''],
                ['swimlane_id', 0],
                ['column_id', 0],
                ['deep', 0],
                ['time_estimated', 0],
                ['owner_id', 0],
            ]);
            if(!$data['title']) $this->error('请输入任务名称');
            if(!$data['description']) $this->error('请输入任务描述');
            if(!$data['time_estimated']) $this->error('请设置计划工时');
            if(!$data['owner_id']) $this->error('请指派给团队成员');
            $data['uid'] = $uid;
            $data['project_id'] = $pro['id'];
            $data['position'] = 0;
            $data['create_at'] = time();
            $data['moved_at'] = time();
            $data['update_at'] = time();
            $res = ProjectTasks::add($data);

            return json($res);
        }
        $users = Db::name('system_admin')->where(function ($query) use($pro) {
                $query->where('id', 'IN', $pro['owner_id'])
                    ->whereOr('id', 'IN', $pro['teams']);
            })
            ->where('is_del', 0)
            ->column('real_name','id');

        $deeps = Config::get('hello.pro_deeps', [1=>'低', 2=>'中', 3=>'高', 4=>'紧急']);
        $swimlanes = Swimlanes::getSwimlanes($pro['id']);
        $columns = ProjectColumns::getColumn($pro['id']);
        $this->assign('users', $users);
        $this->assign('deeps', $deeps);
        $this->assign('swimlanes', $swimlanes);
        $this->assign('columns', $columns);
        $this->assign('pro', $pro);
        $this->assign('uid', $uid);
        $this->assign('swimlane_id', $swimlane_id);
        return $this->fetch('add');
    }

    /**
     * 更新资源
     *
     * @param  \think\Request  $req
     * @return \think\Response
     */
    private function taskEdit($req)
    {
        $id = intval($req->param('id/d'));
        $task_id = intval($req->param('task_id/d'));
        if(!$id || !$task_id) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $pro_owners = explode(',', $pro['owner_id']);
        if(!in_array($uid, $pro_owners)) $this->error('该项目您无权修改任务','',-1);
        $task = ProjectTasks::find(['id'=>$task_id]);
        if(!$task || $task['is_delete']) $this->error('项目不存在或已删除','',-1);

        if ($req->isPost()) {
            $data = Util::postMore([
                ['title', ''],
                ['description', ''],
                //['swimlane_id', 0],
                //['column_id', 1],
                ['deep', 1],
                ['time_estimated', 0],
                ['owner_id', 0],
            ]);
            if(!$data['title']) $this->error('请输入任务名称');
            if(!$data['description']) $this->error('请输入任务描述');
            if(!$data['time_estimated']) $this->error('请设置计划工时');
            if(!$data['owner_id']) $this->error('请指派给团队成员');
            $data['uid'] = $uid;
            //if( $task['column_id'] != $data['column_id'] ) $data['moved_at'] = time();
            $data['update_at'] = time();
            $res = ProjectTasks::edit($data, $task_id);
            Projects::update(['update_at'=>time()], ['id'=>$id]);
            return json($res);
        }
        $users = Db::name('system_admin')
            ->where(function ($query) use($pro) {
                $query->where('id', 'IN', $pro['owner_id'])->whereOr('id', 'IN', $pro['teams']);
            })
            ->where('is_del', 0)
            ->column('real_name','id');

        $deeps = Config::get('hello.pro_deeps', [1=>'低', 2=>'中', 3=>'高', 4=>'紧急']);
        $swimlanes = Swimlanes::getSwimlanes($pro['id']);
        $columns = ProjectColumns::getColumn($pro['id']);
        $this->assign('task', $task);
        $this->assign('users', $users);
        $this->assign('deeps', $deeps);
        $this->assign('swimlanes', $swimlanes);
        $this->assign('columns', $columns);
        $this->assign('pro', $pro);
        $this->assign('uid', $uid);
        return $this->fetch('edit');
    }

    /**
     * 删除任务
     * @param $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function taskDel($req)
    {
        $id = intval($req->param('id/d'));
        $task_id = intval($req->param('task_id/d'));
        if(!$id || !$task_id) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $pro_owners = explode(',', $pro['owner_id']);
        if(!in_array($uid, $pro_owners)) $this->error('该项目您无权删除任务','',-1);
        $task = ProjectTasks::find(['id'=>$task_id]);
        if(!$task || $task['is_delete']) $this->error('项目不存在或已删除','',-1);

        if ($req->isAjax()) {
            if(ProjectTasks::remove($task_id, $id)) {
                $this->success('删除成功');
            } else {
                $this->error('删除失败');
            }
        }
    }

    /**
     * 收缩展开+看自己看全部
     * @param $req
     * @throws \think\db\exception\DbException
     */
    private function change($req)
    {
        $id = intval($req->param('id/d'));
        $to = intval($req->param('to/d',0));
        $event = $req->param('event','');
        if(!$id) $this->error('参数错误');
        if($event != 'collapsed' && $event != 'only') $this->error('参数错误');
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误');
        if($pro['is_delete']) $this->error('项目已删除');
        if(!$to) {
            Db::name('project_user_event')->where('project_id', $id)->where('uid', $uid)->where('event', $event)->delete();
        } else {
            Db::name('project_user_event')->insert(['project_id'=>$id, 'uid'=>$uid, 'event'=>$event]);
        }
        $this->success('ok');
    }

    /**
     * 泳道展示
     * @param $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function swimlane($req)
    {
        $id = intval($req->param('id/d'));
        if(!$id) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $pro_owners = explode(',', $pro['owner_id']);
        if(!in_array($uid, $pro_owners)) $this->error('该项目您无设置权限','',-1);

        if ($req->isAjax()) {
            $data = [];
            $data['count'] = 0;
            $data['data'] = Swimlanes::getSwimlanes($pro['id']);
            $data['code'] = 0;
            $data['msg'] = '';
            return json($data);
        }

        $this->assign('pro', $pro);
        $this->assign('uid', $uid);
        return $this->fetch('swimlane');
    }

    /**
     * 添加泳道
     * @param $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function swimlaneAdd($req)
    {
        $id = intval($req->param('id/d'));
        if(!$id) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $pro_owners = explode(',', $pro['owner_id']);
        if(!in_array($uid, $pro_owners)) $this->error('该项目您无设置权限','',-1);

        if ($req->isPost()) {
            $data = Util::postMore([
                ['name', ''],
                ['description', ''],
            ]);
            if(!$data['name']) $this->error('请设置泳道名称');
            $data['project_id'] = $id;
            $data['position'] = Swimlanes::where('project_id', $id)->max('position') + 1;
            $data['update_at'] = time();
            if(Swimlanes::create($data)) {
                Projects::update(['update_at'=>time()], ['id'=>$id]);
                $this->success('添加成功');
            } else {
                $this->error('添加失败');
            }
        }
        return $this->fetch('swimlane_add');
    }

    /**
     * 修改泳道
     * @param $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function swimlaneEdit($req)
    {
        $id = intval($req->param('id/d'));
        $sid = intval($req->param('sid/d'));
        if(!$id || !$sid) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $pro_owners = explode(',', $pro['owner_id']);
        if(!in_array($uid, $pro_owners)) $this->error('该项目您无设置权限','',-1);
        $swim = Swimlanes::where('id', $sid)->where('project_id', $id)->find();
        if(!$swim) $this->error('参数错误','',-1);

        if ($req->isPost()) {
            $data = Util::postMore([
                ['name', ''],
                ['description', ''],
            ]);
            if(!$data['name']) $this->error('请设置泳道名称');
            $data['update_at'] = time();
            if(Swimlanes::update($data, ['id'=>$sid])) {
                Projects::update(['update_at'=>time()], ['id'=>$id]);
                $this->success('修改成功');
            } else {
                $this->error('修改失败');
            }
        }
        $this->assign('swim', $swim);
        return $this->fetch('swimlane_edit');
    }

    /**
     * 删除泳道
     * @param $req
     * @return string|\think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function swimlaneDel($req)
    {
        $id = intval($req->param('id/d'));
        $sid = intval($req->param('sid/d'));
        if(!$id || !$sid) $this->error('参数错误','',-1);
        $uid = intval($this->adminId);
        $pro = Projects::get($id);
        if(!$pro) $this->error('参数错误','',-1);
        if($pro['is_delete']) $this->error('项目已删除','',-1);
        $pro_owners = explode(',', $pro['owner_id']);
        if(!in_array($uid, $pro_owners)) $this->error('该项目您无权调整泳道','',-1);
        $swim = Swimlanes::where('id', $sid)->where('project_id', $id)->find();
        if(!$swim) $this->error('参数错误','',-1);

        if ($req->isAjax()) {
            if(Swimlanes::remove($sid, $id)) {
                Projects::update(['update_at'=>time()], ['id'=>$id]);
                $this->success('删除成功');
            } else {
                $this->error('删除失败');
            }
        }
    }
    /**
     * Ajax获取团队列表
     *
     * @param  \think\Request  $req
     * @return \think\Response
     */
    public function public_ajax_team(Request $req)
    {
        if ($req->isPost()) {
            $id = $req->param('id/d', 0);
            if($id && $pro = Projects::get($id)) {
                $owners = $pro['owner_id'] ? Db::name('system_admin')->where('id', 'IN',$pro['owner_id'])->column('real_name', 'id') : ['--/--'];
                $audits = $pro['audit_id'] ? Db::name('system_admin')->where('id', 'IN',$pro['audit_id'])->column('real_name', 'id') : ['--/--'];
                $teams = $pro['teams'] ? Db::name('system_admin')->where('id', 'IN', $pro['teams'])->column('real_name', 'id') : ['--/--'];
                $html = '<div><dl class="layui-team-tips">';
                foreach($owners as $owner_name) {
                    $html .= '<dd>负责人：'.$owner_name.'</dd>';
                }
                foreach($teams as $team) {
                    $html .= '<dd>成　员：'.$team.'</dd>';
                }
                foreach($audits as $audit) {
                    $html .= '<dd>审　计：'.$audit.'</dd>';
                }

                $html .= '</dl></div>';
                return json(['code'=>1, 'html'=>$html]);
            }
            return json(['code'=>0]);
        }
        return json(['code'=>0]);
    }
}
